/**
 * @class 深空天体构造器
 * @author DuskyHuang 圣子
 * @description 提供群（双）星系统、星云、星团、河外星系实体的创建。
*/

import { _decorator, Prefab, JsonAsset, instantiate, Node, } from 'cc';
import { Mediator, core } from 'cfw';
import { DeepSkyFixed } from 'prefabs';
import { CosmosController } from '../controllers/cosmos-controller';
import { createNodeAt } from 'helpers';
import { LAYER_BG_3D, SceneGraph } from 'const';
import { Task, TaskNames } from 'notifications';
import { cosmos, CosmosProxy } from '../proxies/cosmos-proxy';
const { ccclass, property } = _decorator;

@ccclass('cocosmos.deep-sky-builder')
export class DeepSkyBuilder extends Mediator {

    @property(JsonAsset) public json: JsonAsset = null;
    @property(Prefab) public DeepSkyFixed: Prefab = null;

    public readonly deepMap = new Map<string, DeepSkyFixed>();
    public readonly nebulas: DeepSkyFixed[] = [];
    public readonly clusters: DeepSkyFixed[] = [];
    public readonly inners: DeepSkyFixed[] = [];
    public readonly galaxies: DeepSkyFixed[] = [];
    public readonly locals: DeepSkyFixed[] = [];
    public readonly virgos: DeepSkyFixed[] = [];

    protected onLoad(): void { this._init(); }

    protected start(): void {
        this._buildDeepSkyObjects();
    }

    public lateUpdate(): void {
        if (!DeepSkyFixed.LoadTexTaskLaunched && (cosmos.pow10 >= CosmosProxy.Scopes.MilkyWay[0])) {
            DeepSkyFixed.LoadTexTaskLaunched = true;
            this.notify(Task.Load.DYNAMIC_TEX, TaskNames.TEX_MSR_INNERS);
            this.notify(Task.Load.DYNAMIC_TEX, TaskNames.TEX_MSR_GALAXIES);
        }
    }

    private _buildDeepSkyObjects(): void {
        const viewer = this._csc.mainCamera.node;
        for (const key in this.json.json) {
            const config: deepSkyConfig = this.json.json[key];
            const node = instantiate(this.DeepSkyFixed);
            const fixed = node.getComponent(DeepSkyFixed);
            fixed.viewer = viewer;
            if (fixed.loadConfig(key, config)) {
                switch (true) {
                    case fixed.nebular: {
                        this.nebulas.push(fixed);
                        this.inners.push(fixed);
                        fixed.node.parent = this._nebulas;
                    } break;
                    case fixed.clustered: {
                        this.clusters.push(fixed);
                        this.inners.push(fixed);
                        fixed.node.parent = this._clusters;
                    } break;
                    case fixed.local: {
                        this.locals.push(fixed);
                        this.galaxies.push(fixed);
                        fixed.node.parent = this._localGalaxies;
                    } break;
                    default: {
                        this.virgos.push(fixed);
                        this.galaxies.push(fixed);
                        fixed.node.parent = this._virgoGalaxies;
                    } break;
                }
            } else console.error(key);
        }
    }

    private _nebulas: Node;
    private _clusters: Node;
    private _localGalaxies: Node;
    private _virgoGalaxies: Node;
    private _csc: CosmosController;
    private _init(): void {
        const milky = this.node.parent.getChildByName(MILKY);
        const local = this.node.parent.getChildByName(LOCAL);
        const virgo = this.node.parent.getChildByName(VIRGO);
        this._nebulas = createNodeAt(Milky.NEBULAS, LAYER_BG_3D, milky);
        this._clusters = createNodeAt(Milky.CLUSTERS, LAYER_BG_3D, milky);
        this._localGalaxies = createNodeAt(Local.GALAXIES, LAYER_BG_3D, local);
        this._virgoGalaxies = createNodeAt(Virgo.GALAXIES, LAYER_BG_3D, virgo);
        this._csc = core.getController(CosmosController);
    }
}

const { MILKY, LOCAL, VIRGO, Milky, Local, Virgo } = SceneGraph;